﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace MyThreadShow
{
    public partial class Form4InvokeAndBeginInvoke : Form
    {
        /******************实验结果***********************
            btnDelegateBeginInvoke_Click:InvokeUIThread,id:10,IsThreadPoolThread:False
            before BeginInvoke Action:,id:15,IsThreadPoolThread:False
            after BeginInvoke Action:,id:15,IsThreadPoolThread:False
            end go:,id:14,IsThreadPoolThread:True
            AsyncCallback :,id:14,IsThreadPoolThread:True
           
            btnDelegateInvoke_Click:InvokeUIThread,id:10,IsThreadPoolThread:False
            before BeginInvoke Action:,id:16,IsThreadPoolThread:False
            end go:,id:16,IsThreadPoolThread:False
            after BeginInvoke Action:,id:16,IsThreadPoolThread:False
         
            btnStartInvoke_Click:InvokeUIThread,id:10,IsThreadPoolThread:False
            before invoke Action:,id:17,IsThreadPoolThread:False
            end go:InvokeUIThread,id:10,IsThreadPoolThread:False
            after invoke Action:,id:17,IsThreadPoolThread:False
         
            btnStartBeginInvoke_Click:InvokeUIThread,id:10,IsThreadPoolThread:False
            before BeginInvoke Action:,id:18,IsThreadPoolThread:False
            after BeginInvoke Action:,id:18,IsThreadPoolThread:False
            end go:InvokeUIThread,id:10,IsThreadPoolThread:False
         * ***************************************************************************/
        public Form4InvokeAndBeginInvoke()
        {
            InitializeComponent();
            Thread.CurrentThread.Name = "InvokeUIThread";
            invokeDelegate = go;
            beginInvokeDelegate = go;
        }

        private void btnStartInvoke_Click(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("btnStartInvoke_Click:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
            Thread t = new Thread(
                new ThreadStart(
                    new Action(()=>{
                        Console.WriteLine(string.Format("before invoke Action:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
                        this.Invoke(new Action(go));
                        Console.WriteLine(string.Format("after invoke Action:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
                    })));
            t.IsBackground = true;
            t.Start();
        }

        private void btnStartBeginInvoke_Click(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("btnStartBeginInvoke_Click:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
            Thread t = new Thread(
               new ThreadStart(
                   new Action(() =>
                   {
                       Console.WriteLine(string.Format("before BeginInvoke Action:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
                       this.BeginInvoke(new Action(go));
                       Console.WriteLine(string.Format("after BeginInvoke Action:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
                   })));
            t.IsBackground = true;
            t.Start();
        }
        
        void go()
        {
          // btnStartInvoke.Text = "Starting……";
            Thread.Sleep(10000);
            Console.WriteLine(string.Format("end go:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
        }

        private void btnDelegateBeginInvoke_Click(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("btnDelegateBeginInvoke_Click:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
            Thread t = new Thread(
           new ThreadStart(
               new Action(() =>
               {
                   Console.WriteLine(string.Format("before BeginInvoke Action:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
                   invokeDelegate.BeginInvoke(AsyncCallback, this);
                   Console.WriteLine(string.Format("after BeginInvoke Action:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
               })
               ));
            t.IsBackground = true;
            t.Start();
        }

        private void btnDelegateInvoke_Click(object sender, EventArgs e)
        {
            Console.WriteLine(string.Format("btnDelegateInvoke_Click:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
            Thread t = new Thread(
           new ThreadStart(
               new Action(()=>{
                   Console.WriteLine(string.Format("before BeginInvoke Action:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
                   invokeDelegate.Invoke();
                   Console.WriteLine(string.Format("after BeginInvoke Action:{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
               })
               ));
            t.IsBackground = true;
            t.Start();
        }

        void AsyncCallback(IAsyncResult ar)
        {
            Console.WriteLine(string.Format("AsyncCallback :{0},id:{1},IsThreadPoolThread:{2}", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread));
            Thread.Sleep(10000);

        }

        InvokeDelegate invokeDelegate;
        BeginInvokeDelegate beginInvokeDelegate;
    }

    public delegate void InvokeDelegate();
    public delegate void BeginInvokeDelegate();
}
